/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package py.una.pol.ejb.compraventa.dao;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Id;
import javax.persistence.PersistenceContext;

/**
 *
 * @author claudia
 */
public class GenericDaoImpl <T> implements GenericDao<T> {

    @PersistenceContext(unitName = "CompraVentaEJBPU")
    private EntityManager em;
    private Class<T> beanClass;

    @Override
    public T findById(Object id) {
        if (id == null) {
            return null;
        }
        return em.find(getClassOfT(), id);
    }

    public void insert(T object) {
        em.persist(object);
    }

    public void update(T object) {
        em.merge(object);
    }

    @SuppressWarnings("unchecked")
    public List<T> findAll() {
        return em.createQuery("SELECT u FROM " + getClassName() + " as u").getResultList();
    }

    @Override
    public void delete(T object) {
        System.out.println("INTENTANDO BORRAR EL OBJETO: " + object);
        Object id = getIdValue(object);
        if (id == null) {
            System.out.println("NO SE RECUPERO ID DEL OBJETO: " + object);
            return;
        }
        T tmp = findById(id);
        if (tmp != null) {
            em.remove(tmp);
        } else {
            System.out.println("NO SE RECUPERO OBJETO: " + object);
        }
    }

    @SuppressWarnings("unchecked")
    public Class<T> getClassOfT() {
        if (beanClass == null) {
            ParameterizedType superClass = (ParameterizedType) getClass()
                    .getGenericSuperclass();
            beanClass = (Class<T>) superClass.getActualTypeArguments()[0];

        }
        return beanClass;
    }

    private String getClassName() {
        return getClassOfT().getSimpleName();
    }

    /**
     * Recibe un objeto y retorna el valor de su primaryKey
     *
     */
    public Object getIdValue(Object obj) {
        if (obj == null) {
            return null;
        }
        try {
            for (Field field : obj.getClass().getDeclaredFields()) {
                if (field.isAnnotationPresent(Id.class)) {
                    field.setAccessible(true);
                    Object data = field.get(obj);
                    field.setAccessible(false);
                    return data;
                }
            }
            return null;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    ;
    
    public EntityManager getEntityManager() {
        return em;
    }
}
